package com.xhorse.lockplatform.service.impl;

import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.PushPayload.Builder;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.audience.AudienceTarget;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import com.alibaba.fastjson.JSONObject;
import com.xhorse.lockplatform.comm.constant.ConstantString;
import com.xhorse.lockplatform.comm.enums.ResultEnum;
import com.xhorse.lockplatform.comm.exception.LockPlatFormException;
import com.xhorse.lockplatform.comm.model.BaseQuery;
import com.xhorse.lockplatform.comm.service.BaseService;
import com.xhorse.lockplatform.comm.util.HttpClientUtil;
import com.xhorse.lockplatform.comm.util.Paginator;
import com.xhorse.lockplatform.dao.mapper.XhJpushListMapper;
import com.xhorse.lockplatform.model.XhJpushList;
import com.xhorse.lockplatform.service.JpushService;
import okhttp3.FormBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class JpushServiceImpl extends BaseService<XhJpushList> implements JpushService {

    @Autowired
    private XhJpushListMapper xhJpushListMapper;

    @Value("${jpush.appKey}")
    private String appKey;
    @Value("${jpush.masterSecret}")
    private String masterSecret;

    Map<String, String> extras = new HashMap<>(); // type类型：
    // 1.固件升级、2.遥控数据更新、3.48计算结果通知、4.展示（预留）

    private Logger log = Logger.getLogger(JpushServiceImpl.class);

    /**
     * 48计算结果通知
     */
    @Override
    public boolean pushCountResult(XhJpushList xhJpushList) {
        JPushClient jPushClient = new JPushClient(masterSecret, appKey);
        String customer_id = xhJpushList.getCustomerId() + "";
        String sn = xhJpushList.getSn();
        int regionId = xhJpushList.getRegionId();
        String countResult = null;
        extras.put("type", "3");
        PushPayload pushPayload = null;
        if (regionId == 8) {
            countResult = ConstantString.COUTN_RESULT_CN_PREFIX + sn
                    + ConstantString.COUTN_RESULT_CN_SUFFIX;
            extras.put("title", "48计算");
        } else {
            countResult = ConstantString.COUTN_RESULT_EN_PREFIX + sn
                    + ConstantString.COUTN_RESULT_EN_SUFFIX;
            extras.put("title", "Cpoy 48(96bit) calculation");
        }
        pushPayload = buildPushLoad(customer_id, null, countResult, 1, extras);
        try {
            PushResult result = jPushClient.sendPush(pushPayload);
            if (result.statusCode == 0) {
                xhJpushList.setDone((byte) 1);
                xhJpushListMapper.updateByPrimaryKeySelective(xhJpushList);
            }
        } catch (APIConnectionException | APIRequestException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 遥控数据更新通知
     */
    @Override
    public void pushUpdateInfo(int regionId) {
        JPushClient jPushClient = new JPushClient(masterSecret, appKey);
        String information = null;
        PushPayload pushPayload = null;
        extras.put("type", "2");
        for (int i = 1; i < 18; i++) {
            switch (i) {
                case 1:
                    information = ConstantString.REMOTE_RESULT_CN;
                    extras.put("title", "遥控数据升级");
                    pushPayload = buildPushLoad(regionId + "", "L_" + i,
                            information, 2, extras);
                    try {
                        PushResult result = jPushClient.sendPush(pushPayload);
                        log.debug(result);
                    } catch (APIConnectionException | APIRequestException e) {
                    }
                    break;
                case 2:
                    information = ConstantString.REMOTE_RESULT_EN;
                    extras.put("title", "firmware upgrage");
                    pushPayload = buildPushLoad(regionId + "", "L_" + i,
                            information, 2, extras);
                    try {
                        PushResult result = jPushClient.sendPush(pushPayload);
                        log.debug(result);
                    } catch (APIConnectionException | APIRequestException e) {
                    }
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 固件更新推送
     */
    @Override
    public void hardwareInfoPush(int regionId) {
        JPushClient jPushClient = new JPushClient(masterSecret, appKey);
        String information = null;
        PushPayload pushPayload = null;
        extras.put("type", "1");
        for (int i = 1; i < 18; i++) {
            switch (i) {
                case 1:
                    information = ConstantString.FIRMWARE_RESULT_CN;
                    extras.put("title", "升级公告");
                    pushPayload = buildPushLoad(regionId + "", "L_" + i,
                            information, 2, extras);
                    try {
                        PushResult result = jPushClient.sendPush(pushPayload);
                        log.debug(result);
                    } catch (APIConnectionException | APIRequestException e) {
                        continue;
                    }
                    break;
                case 2:
                    information = ConstantString.FIRMWARE_RESULT_EN;
                    extras.put("title", "UPDATEA INFOMATION");
                    pushPayload = buildPushLoad(regionId + "", "L_" + i,
                            information, 2, extras);
                    try {
                        PushResult result = jPushClient.sendPush(pushPayload);
                        log.debug(result);
                    } catch (APIConnectionException | APIRequestException e) {
                        continue;
                    }
                    break;
                default:
                    break;
            }
        }

    }

    /**
     * 构建推送服务
     *
     * @param regionId
     * @param information
     * @param type
     * @return
     */
    private PushPayload buildPushLoad(String regionId, String languageId,
                                      String information, int type, Map<String, String> extras) { // type:
        // 1.指定用户发送，2.群组用户发送
        Builder pushBuiler = new Builder();
        pushBuiler.setPlatform(Platform.all());
        if (type == 1) { // 向特定用户发送推送
            pushBuiler.setAudience(Audience.newBuilder()
                    .addAudienceTarget(AudienceTarget.alias(regionId)).build());
        } else { // 向群组用户发送推送
            pushBuiler.setAudience(Audience
                    .newBuilder()
                    .addAudienceTarget(
                            AudienceTarget.tag_and(regionId, languageId))
                    .build());
        }
        pushBuiler.setOptions(Options.newBuilder().setApnsProduction(false)
                .build());
        pushBuiler.setNotification(Notification
                .newBuilder()
                .addPlatformNotification(
                        IosNotification.newBuilder().setAlert(information)
                                .setBadge(0).setSound("default")
                                .addExtras(extras).build())
                .addPlatformNotification(
                        AndroidNotification.newBuilder().setAlert(information)
                                .addExtras(extras).build()).build());
        return pushBuiler.build();
    }

    /**
     * 获取推送列表
     */
    @Override
    public List<XhJpushList> queryForResult() {
        HttpClientUtil httpClientUtil = HttpClientUtil.getInstance();
        //生成验证token，供php服务器验证使用
        String verToken = httpClientUtil
                .verTokenGenerate(ConstantString.USERNAME);
        RequestBody requestBody = new FormBody.Builder().add("cmd", "22").build();
        Request request = new Request.Builder()
                .url(ConstantString.PHP_URL_DATATRANSFER)
                .addHeader("verToken", verToken).post(requestBody).build();
        try {
            Response response = httpClientUtil.getClient().newCall(request).execute();
            String result = String.valueOf(response.body());
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (jsonObject.getIntValue("error_code") != 0) {
                List<XhJpushList> list = JSONObject.parseArray(jsonObject.getString("list"), XhJpushList.class);
                for (XhJpushList xhJpushList : list) {
                    Paginator paginator = new Paginator();
                    Query query = new Query();
                    query.setCustomerId(xhJpushList.getCustomerId());
                    query.setSn(xhJpushList.getSn());
                    // 根据条件查询列表
                    List<XhJpushList> temp = xhJpushListMapper.select(paginator);
                    if (temp.isEmpty()) {
                        xhJpushListMapper.insertSelective(xhJpushList);
                    } else {
                        xhJpushListMapper.updateByPrimaryKeySelective(xhJpushList);
                    }
                }
                return list;
            }
        } catch (IOException e) {
            throw new LockPlatFormException(ResultEnum.FAILED.getCode(), "获取推送列表，遇到异常", e);
        }
        return null;
    }

    /**
     * 自定义推送
     */
    @Override
    public boolean customPushInfo(String[] infoList, int[] languageIdList) {
        JPushClient jPushClient = new JPushClient(masterSecret, appKey);
        Builder pushBuilder = new Builder();
        Map<String, String> extras = new HashMap<>();
        extras.put("type", "4");
        pushBuilder.setPlatform(Platform.all());
        pushBuilder.setOptions(Options.newBuilder().setApnsProduction(false)
                .build());
        for (int i = 0; i < infoList.length; i++) {
            pushBuilder.setAudience(Audience.tag(languageIdList[i] + ""))
                    .setNotification(
                            Notification
                                    .newBuilder()
                                    .addPlatformNotification(
                                            IosNotification.newBuilder()
                                                    .setAlert(infoList[i])
                                                    .setBadge(0)
                                                    .setSound("default")
                                                    .addExtras(extras).build())
                                    .addPlatformNotification(
                                            AndroidNotification.newBuilder()
                                                    .setAlert(infoList[i])
                                                    .addExtras(extras).build())
                                    .build());
            PushPayload pushPayload = pushBuilder.build();
            try {
                jPushClient.sendPush(pushPayload);
            } catch (Exception e) {
                throw new LockPlatFormException(ResultEnum.FAILED.getCode(), "自定义推送，遇到异常", e);
            }
        }
        return true;
    }

    public static class Query extends BaseQuery {
        private int customerId;
        private String sn;

        public void setCustomerId(int customerId) {
            this.customerId = customerId;
            this.addItem("customerId", customerId);
        }

        public void setSn(String sn) {
            this.sn = sn;
            this.addItem("sn", sn);
        }
    }
}
